/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package geradordao;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

/**
 *
 * @author Iana
 */
public class AnalisadorLexico {

    private List<Token> tokens = new ArrayList<Token>();
    private BufferedReader br;
    private List<String> erros = new ArrayList<String>();
    private List<String> controle = new ArrayList<String>();

    public AnalisadorLexico(BufferedReader br) {
        this.br = br;
    }

    public void analisar() throws IOException {
        int nLinha = 1;
        String linha = br.readLine();
        while (linha != null) {
            StringTokenizer tokenizador = new StringTokenizer(linha);
            while (tokenizador.hasMoreTokens()) {
                String imagem = tokenizador.nextToken();

                Token token = new Token();
                token.setImagem(imagem);
                token.setLinha(nLinha);
                token.setColuna(linha.indexOf(imagem) + 1);
                if (imagem.charAt(imagem.length() - 1) == '"' && imagem.length() > 1) {
                    erros.add("Erro léxico: erro de formação de string. Linha: " + nLinha + " - Imagem:" + imagem);
                    break;
                } else if (TabelasEstaticas.ehComentario(imagem)) {
                    token.setClasse(Token.CLASSE_COMENTARIO);
                } else if (TabelasEstaticas.ehPalavraReservada(imagem)) {
                    token.setClasse(Token.CLASSE_PALAVRA_RESERVADA);
                    tokens.add(token);
                } else if (TabelasEstaticas.ehDelimitador(imagem)) {
                    token.setClasse(Token.CLASSE_DELIMITADOR);
                    tokens.add(token);
                } else if (imagem.charAt(0) == '"') {
                    String retLinha = cortaString(linha, nLinha, (linha.indexOf(imagem) + 1));
                    tokenizador = new StringTokenizer(retLinha);
                } else if (imagem.matches("\\d+")) {
                    token.setClasse(Token.CLASSE_CONSTANTE_LITERAL_INTEIRA);
                    tokens.add(token);
                } else if (imagem.matches("\\d+\\.\\d+")) {
                    token.setClasse(Token.CLASSE_CONSTANTE_LITERAL_REAL);
                    tokens.add(token);
                } else if (imagem.equalsIgnoreCase("tue") || imagem.equalsIgnoreCase("false")) {
                    token.setClasse(Token.CLASSE_CONSTANTE_LITERAL_BOOLEANA);
                    tokens.add(token);
                } else if (imagem.matches("\\p{Alpha}\\p{Alnum}*")) {
                    token.setClasse(Token.CLASSE_IDENTIFICADOR);
                    tokens.add(token);
                    //TabelaSimbolos.addSimbolo(token);
                } else {
                    erros.add("Palavra não reconhecida. Linha " + nLinha + " - Imagem: " + imagem + " - Coluna: " + (linha.indexOf(imagem) + 1));
                    break;
                }
            }
            linha = br.readLine();
            nLinha++;
        }
    }

    private String cortaString(String linha, int nLinha, int ncol) {
        int inicioString = linha.indexOf('"');
        String subLinha = linha.substring(inicioString + 1);
        int fimString = subLinha.indexOf('"');

        if (fimString == -1) {
            erros.add("Erro léxico: erro de formação de string. Linha " + nLinha + " - Imagem:" + linha);
            return "";
        } else {
            String imagem = linha.substring(inicioString + 1, inicioString + fimString + 1);
            Token token = new Token();
            token.setImagem(imagem);
            token.setClasse(Token.CLASSE_CONSTANTE_LITERAL_STRING);
            token.setLinha(nLinha);
            token.setColuna(ncol);
            tokens.add(token);
        }
        return subLinha.substring(fimString + 1);
    }

    public boolean temErros() {
        return erros.size() > 0;
    }

    public void mostraErros() {
        for (String erro : erros) {
            System.out.println(erro);
        }
    }

    public List<Token> getTokens() {
        return tokens;
    }

    public void mostraTokens() {
        System.out.println("======Tabela de Tokens======");
        for (Token tok : tokens) {
            System.out.println(tok);

        }
    }

    public void mostraIds() {
        System.out.println("======Tabela de Indices======");
        for (Token tok : tokens) {
            if (tok.getClasse().equals(Token.CLASSE_IDENTIFICADOR) && !tok.getJaExisteId()) {
                System.out.println("indice: " + tok.getIndice() + " token: " + tok.getImagem());
            }
        }
    }
}
